package cValidator

import (
	"fmt"
	"gitee.com/csingo/cHelper"
	"github.com/gin-gonic/gin"
	"github.com/hashicorp/go-multierror"
)

type Validator struct {
	App   string
	Name  string
	Scene string
}

func rules(validators []*Validator) (rules []*ValidatorRule) {
	rules = make([]*ValidatorRule, 0)
	for _, item := range validators {
		index := item.App + "." + item.Name
		validator := container.Get(index)
		if validator == nil {
			continue
		}

		itemRules := validator.(ValidatorInterface).Rules()
		if rule, ok := itemRules[item.Scene]; ok && len(rule) > 0 {
			rules = append(rules, rule...)
		}
	}

	return
}

func Validate(ctx *gin.Context, validators []*Validator, data any) (err error) {
	rs := rules(validators)

	vData := map[string]any{}
	vRule := map[string]any{}
	for _, r := range rs {
		values := cHelper.GetFieldValues(r.Field, data)
		for i, value := range values {
			field := fmt.Sprintf("%s.%d", r.Field, i)
			vData[field] = value

			if vRule[field] != nil {
				vRule[field] = fmt.Sprintf("%s,%s", vRule[field], r.Rules)
			} else {
				vRule[field] = r.Rules
			}
		}

	}

	errs := Verifier.ValidateMapCtx(ctx, vData, vRule)
	for f, e := range errs {
		err = multierror.Append(err, fmt.Errorf("%s: %s", f, e))
	}

	return
}
